package com.yeyks.consumer.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yeyks.common.exception.ServiceException;
import com.yeyks.consumer.dal.dao.FishBallBillMapper;
import com.yeyks.consumer.dal.dao.FishBallMapper;
import com.yeyks.consumer.dal.domain.FishBall;
import com.yeyks.consumer.dal.domain.FishBallBill;
import com.yeyks.consumer.service.FishBallService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;


/**
 * <p>
 * 鱼宝表 服务实现类
 * </p>
 *
 * @author yun
 * @since 2019-06-25
 */
@Slf4j
@Service
public class FishBallServiceImpl extends ServiceImpl<FishBallMapper, FishBall> implements FishBallService {

    @Autowired
    private FishBallBillMapper fishBallBillMapper;

    /**
     * 通过用户的id查询用户的鱼宝账户信息(没有则创建)
     *
     * @param userId
     * @return
     */
    @Override
    public FishBall getFishBallNoCreate(Integer userId) {
        FishBall fishBall = baseMapper.selectFishBallByUserId(userId);
        if (fishBall == null) {
            fishBall = getFishBall(userId);
            int res = baseMapper.insert(fishBall);
            if (res != 1) {
                log.error("鱼宝账户创建异常userId = {}", userId);
                return null;
            }
        }
        return fishBall;
    }

    /**
     * 增加鱼宝数
     *
     * @param amount 操作鱼宝数
     * @param userId 用户id
     * @param remark 备注
     * @param type   账单类型：1  获取鱼宝  2  消费鱼宝
     * @return
     */
    @Override
    @Transactional
    public Integer addFishBall(Integer amount, Integer userId, Integer type, String remark) {
        try {
            if (amount == null) {
                amount = 0;
            }
            FishBall fishBall = getFishBallNoCreate(userId);
            fishBall.setTotalAmount(fishBall.getTotalAmount() == null ? 0 : fishBall.getTotalAmount() + amount);
            fishBall.setUpdateTime(new Date());
            baseMapper.updateById(fishBall);
            FishBallBill fishBallBill = getFishBallBill(fishBall, amount, remark, type);
            fishBallBillMapper.insert(fishBallBill);
            return fishBallBill.getAvaliableAmount().intValue();
        } catch (Exception e) {
            log.error("增加鱼宝数异常{}", e.getLocalizedMessage());
            return -1;
        }
    }

    private FishBallBill getFishBallBill(FishBall fishBall, Integer amount, String remark, Integer type) {

        FishBallBill fishBallBill = new FishBallBill();
        fishBallBill.setUserId(fishBall.getUserId());
        fishBallBill.setOperatorAmount(Long.valueOf(amount));
        fishBallBill.setRemark(remark);
        fishBallBill.setType(type);
        int totalAmount = fishBall.getTotalAmount() == null ? 0 : fishBall.getTotalAmount();
        int useAmount = fishBall.getUseAmount() == null ? 0 : fishBall.getUseAmount();
        int avaliable = totalAmount - useAmount < 0 ? 0 : totalAmount - useAmount;
        fishBallBill.setAvaliableAmount((long) avaliable);
        fishBallBill.setCreatedTime(new Date());
        return fishBallBill;
    }

    /**
     * 减少鱼宝数
     *
     * @param amount 操作鱼宝数
     * @param userId 用户id
     * @param remark 备注
     * @param type   账单类型：1  获取鱼宝  2  消费鱼宝
     * @return 返回可用余额数（失败返回-1）
     */
    @Override
    @Transactional
    public Integer descFishBall(Integer amount, Integer userId, String remark, Integer type) {
        try {
            if (amount == null) {
                amount = 0;
            }
            FishBall fishBall = getFishBallNoCreate(userId);
            int remainAmount = fishBall.getTotalAmount() - fishBall.getUseAmount() < 0 ? 0 : fishBall.getTotalAmount() - fishBall.getUseAmount();
            if (amount > remainAmount) {
                log.info("减少鱼宝数失败,消费鱼宝数{}，鱼宝余额{}", amount, fishBall.getTotalAmount());
                throw new ServiceException("可用鱼宝数不足");
            }
            fishBall.setUseAmount(fishBall.getUseAmount() == null ? 0 : fishBall.getUseAmount() + amount);
            fishBall.setUpdateTime(new Date());
            baseMapper.updateById(fishBall);
            FishBallBill fishBallBill = getFishBallBill(fishBall, amount, remark, type);
            fishBallBillMapper.insert(fishBallBill);
            return fishBallBill.getAvaliableAmount().intValue();
        } catch (ServiceException e) {
            throw e;
        } catch (Exception e) {
            log.error("减少鱼宝数异常{}", e.getLocalizedMessage());
            throw e;
        }
    }

    private FishBall getFishBall(Integer userId) {
        FishBall fishBall = new FishBall();
        fishBall.setUserId(Long.valueOf(userId));
        fishBall.setTotalAmount(0);
        fishBall.setUseAmount(0);
        Date date = new Date();
        fishBall.setCreatedTime(date);
        fishBall.setUpdateTime(date);
        return fishBall;
    }


}
